﻿using Jupiter.Infrastructure.Attributes;
using Jupiter.Infrastructure.Cache.Interfaces;
using Jupiter.Infrastructure.Domain.SqlSugar;
using Jupiter.Infrastructure.Domain.SqlSugar.Basic;
using Jupiter.Infrastructure.Exceptions;
using Jupiter.Infrastructure.Mappings;
using Jupiter.Infrastructure.Permission;
using Jupiter.Infrastructure.Permission.DataPermissions;
using Jupiter.Infrastructure.Responses;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Localization;
using Wips.AppService.Publisher.PublishFlows;
using Wips.AppService.Publisher.PublishFlows.Models;
using Wips.AppService.Publisher.PublishFlows.Requests;
using Wips.AppService.Publisher.PublishFlows.Responses;
using Wips.Domain.Models;
using Wips.Domain.Models.Authorities.Model;
using Wips.Infrastructure.Model;

namespace Wips.AppService.SqlSugar.Publisher
{

    /// <summary>
    /// 发布流程创建
    /// </summary>
    [ServiceComponent]
    public class PublishFlowAppService : AppServiceQueryBase<PublishFlow>, IPublishFlowAppService
    {
        private readonly IMapsterMapper _mapsterMapper;
        private readonly PublishMasterService _publishMasterService;
        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="securityContextAccessor"></param>
        /// <param name="configuration"></param>
        /// <param name="cacheManager"></param>
        /// <param name="permission"></param>
        /// <param name="stringLocalizer"></param>
        /// <param name="mapsterMapper"></param>
        public PublishFlowAppService(ISqlSugarClient dbContext, ISecurityContextAccessor securityContextAccessor, IConfiguration? configuration, ICacheManager? cacheManager, IDataPermission? permission, IStringLocalizer? stringLocalizer, IMapsterMapper mapsterMapper, PublishMasterService publishMasterService) : base(dbContext, securityContextAccessor, configuration, cacheManager, permission, stringLocalizer)
        {
            _mapsterMapper = mapsterMapper;
            _publishMasterService = publishMasterService;
        }

        /// <summary>
        /// 获取注册的服务
        /// </summary>
        /// <returns></returns>
        public async Task<PageResult<GetPublishFlowPagesResponse>> GetPageAsync(GetPublishFlowPagesRequest request)
        {

            var permission = await Query<AgentServerPermission>()
                                .Where(c => c.UserId == UserId)
            .ToListAsync();
            var serverIds = permission.Select(c => c.AgentServerId).ToList();
            var serverConfigIds = permission.Select(c => c.AgentServerConfigId).ToList();

            var list = await Query()
                .Includes(c => c.Nodes)
                .Includes(c => c.AgentServerConfig)
                .Includes(c => c.AgentServer)
                .Where(c => serverIds.Contains(c.AgentServerId) || serverConfigIds.Contains(c.AgentServerConfigId))
                .HasWhere(request.PublishFlowStatus, c => c.PublishFlowStatus == request.PublishFlowStatus)
                .ToPageAsync(request);
            var result = _mapsterMapper.MapTo<PageResult<GetPublishFlowPagesResponse>>(list);
            foreach (var item in result.Items)
            {
                var souces = list.Items.Where(c => c.Id == item.Id).FirstOrDefault();

                item.AgentServerName = souces?.AgentServer?.ServerName;
                item.AgentServiceName = souces?.AgentServerConfig?.ServerName;

            }
            return result;
        }



        /// <summary>
        /// 获取发布流程详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<PublishFlowModel> GetById(string id)
        {
            var model = await Query().Includes(c => c.Nodes).Where(c => c.Id == id).FirstOrDefaultAsync();

            if (model == null)
            {
                throw new CoreException("未找到对应数据！");
            }

            return _mapsterMapper.MapTo<PublishFlowModel>(model);

        }




        /// <summary>
        /// 获取对应流程中所有zip文件的目录表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="CoreException"></exception>
        public async Task<List<GetFlowNodeZipFileListResponse>> GetFlowZipFileListAsync(string id)
        {
            var flow = await Query()
                .Includes(c => c.AgentServer)
                .Includes(c => c.Nodes)
                .Where(c => c.Id == id).FirstOrDefaultAsync();
            if (flow == null)
            {
                throw new CoreException("未找到对应发布流程数据！");
            }
            List<GetFlowNodeZipFileListResponse> result = new List<GetFlowNodeZipFileListResponse>();
            foreach (var item in flow.Nodes!)
            {
                var doList = new List<EnumNodeType> { EnumNodeType.BackUp, EnumNodeType.Upload };
                if (doList.IndexOf(item.NodeType) > -1)
                {
                    var r1 = new GetFlowNodeZipFileListResponse();
                    r1.NodeType = item.NodeType;
                    r1.Directorys = new List<DirectoryModel>();
                    var backUp = await _publishMasterService.GetZipFileInfoListAsync(flow.AgentServer!.AgentAddress, item.Result);
                    if (backUp.Success)
                    {
                        r1.Directorys = backUp.Data!.OrderBy(c => c.Path).ToList();
                    }
                    else
                    {
                        r1.IsDeleted = true;
                    }
                    result.Add(r1);
                }

            }
            return result;
        }


        /// <summary>
        /// 获取日志列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<List<PublishFlowLogModel>> GetLogListAsync(string id)
        {
       
            var list = await Query<PublishLog>()
                .Where(c => c.Key == id )
                .OrderBy(c => c.Created, OrderByType.Desc)
                .ToListAsync();

            var allUser = await Query<User>().ToListAsync();

            var res = _mapsterMapper.MapTo<List<PublishFlowLogModel>>(list);
            foreach (var log in res)
            {
                var user = allUser.Where(c => c.Id == log.UserId).FirstOrDefault();
                log.UserName = user?.UserName;
            }
            return res;
        }

    }
}
